import React, { CSSProperties, useEffect, useState } from "react";
import { PickerView, PickerViewColumn, View } from "@tarojs/components";
import {
  PickerProps,
  PickerItemAttribute
} from "../../../types/components/picker-view";

/**
 * Picker
 */
function Picker<T>({
  dataSource,
  defaultValue,
  column = 1,
  linkage,
  onChange,
  columnStyle,
  activeTextStyle,
  textStyle,
  style,
  indicatorStyle, 
  indicatorClass,
  maskClass,
  maskStyle
}: PickerProps<T>) {
  // 设置picker默认植
  const [pickerValue, setPickerValue] = useState<number[]>([]);
  // 1 2 3列数据
  const [pickerData, setPickerData] = useState<PickerItemAttribute<T>[][]>([]);
  useEffect(() => {
    if (dataSource && Array.isArray(dataSource) && dataSource.length > 0) {
      let pickerData: PickerItemAttribute<T>[][] = []; // picker数据源
      let pickerValue: number[] = Array(column).fill(0); // picker选中默认值
      // 1. 设置 pickerData
      if (linkage) {
        // 联动
        let ds: PickerItemAttribute<T>[] = []; // 取一维数组
        if (Array.isArray(dataSource[0])) {
          // 多维数组
          ds = dataSource[0];
        } else {
          ds = dataSource as PickerItemAttribute<T>[];
        }
        let dsT: PickerItemAttribute<T>[] | undefined = ds;
        if (defaultValue && defaultValue.length > 0) {
          // 有默认值，查找colum个数组
          for (let index = 0; index < column; index++) {
            const element = defaultValue[index];
            if (dsT && dsT.length > 0 && element) {
              const index = dsT.findIndex(item => item.value === element);
              const value = index >= 0 ? index : 0;
              // pickerValue.push(value)
              pickerData.push(dsT);
              dsT = dsT[value].children;
            } else {
              console.warn("zdx pickerData defaultValue column 数据长度不一致");
              break;
            }
          }
        } else {
          // 没有默认值直接装填
          for (let index = 0; index < column; index++) {
            if (dsT && dsT.length > 0) {
              pickerData.push(dsT);
              dsT = dsT[0].children;
            }
          }
        }
        setPickerData(pickerData);
      } else {
        // 非联动
        if (Array.isArray(dataSource[0])) {
          // 多维数组
          pickerData = dataSource.slice(0, column) as PickerItemAttribute<
            T
          >[][];
        } else {
          // 一维数组
          pickerData = [dataSource as PickerItemAttribute<T>[]];
        }
        setPickerData(pickerData);
      }
      // 2. 设置默认值
      if (defaultValue && defaultValue.length > 0) {
        pickerValue = []; // 置空后重新装填
        for (let index = 0; index < column; index++) {
          const element = defaultValue[index];
          const data = pickerData[index];
          if (data && element !== undefined) {
            const index = data.findIndex(item => item.value === element);
            pickerValue.push(index >= 0 ? index : 0);
          } else {
            break;
          }
        }
      }
      setPickerValue(pickerValue);
      // 主动回调onChange
      const values = getChangeValues(pickerData, pickerValue, column);
      onChange && onChange(values);
    }
  }, [dataSource, column, linkage, defaultValue, onChange]);

  const onPickerChange = function(e) {
    let indexs: number[] = e.detail.value;
    let pickerDataT = pickerData;
    if (linkage) {
      let pickerDataTT: PickerItemAttribute<T>[][] = [];
      let needReset = false;
      let dsT: PickerItemAttribute<T>[] | undefined = pickerData[0]; // 第1列不会变
      for (let index = 0; index < column; index++) {
        let id = indexs[index]; // 当前更新后的值 index
        const pv = pickerValue[index]; // 上一次的值 index
        // 如果linkage=true，并且当前的变动的是column -1的列就需要 setPickerData
        if (id != pv && index < column - 1) {
          if (!needReset) needReset = true;
          // 同时需要将下个级联列的index置0
          if (indexs.length >= index + 1) {
            indexs[index + 1] = 0;
          }
        }
        dsT && pickerDataTT.push(dsT);
        dsT = dsT && dsT[id].children;
      }
      if (needReset) {
        pickerDataT = pickerDataTT;
        setPickerData(pickerDataTT);
      }
    }
    // 拿到最终的pickerDataT
    setPickerValue(indexs);
    const values = getChangeValues(pickerDataT, indexs, column);
    onChange && onChange(values);
  };

  /**
   * 获取onChange数据
   * @param datas 原始数据
   * @param indexs 每列选中索引
   * @param column 列数
   */
  const getChangeValues = (
    datas: PickerItemAttribute<T>[][],
    indexs: number[],
    column: number
  ) => {
    let values: PickerItemAttribute<T>[] = [];
    for (let index = 0; index < column; index++) {
      const elements = datas[index]; // 列数组
      const row = indexs[index]; // 列对应的行索引
      let value: PickerItemAttribute<T>;
      if (elements && elements[row]) {
        value = elements[row];
        values.push(value);
      }
    }
    return values;
  };

  const getStyle = (index, col): CSSProperties => {
    const active = index === pickerValue[col];
    if (active && activeTextStyle) {
      return activeTextStyle;
    }
    return {
      overflow: "hidden",
      whiteSpace: "nowrap",
      textOverflow: "ellipsis",
      height: 34 + "px",
      lineHeight: 34 + "px",
      fontWeight: active ? 600 : 400,
      color: active ? "#37D9CE" : "#000000",
      ...textStyle
    };
  };

  return (
    <PickerView
      style={{
        height: 430 + "rpx",
        backgroundColor: "#ffffff",
        ...style
      }}
      indicatorStyle={indicatorStyle}
      indicatorClass={indicatorClass}
      maskClass={maskClass}
      maskStyle={maskStyle}
      onChange={onPickerChange}
      value={pickerValue}
    >
      {pickerData && pickerData.length > 0
        ? pickerData.map((d, index) => {
            return (
              <PickerViewColumn
                key={index}
                style={{ textAlign: "center", ...columnStyle }}
              >
                {d.map((item, i) => {
                  return (
                    <View style={getStyle(i, index)} key={i}>
                      {item.label}
                    </View>
                  );
                })}
              </PickerViewColumn>
            );
          })
        : null}
    </PickerView>
  );
}

export default Picker;
